class GameRule {

	/**
	 * 牌型判断
	*/
	public static typeJudge(cards) {
		var l = cards.length;
		switch(l){
			case 1:
				return {'cardKind': GameRule.ONE,'val':cards[0].val,'size':l};
			case 2:
				if(GameRule.isPairs(cards)){
					return {'cardKind': GameRule.PAIRS,'val':cards[0].val,'size':l};
				}else if(GameRule.isKingBomb(cards)){
					return {'cardKind': GameRule.KING_BOMB,'val':cards[0].val,'size':l};
				}else{
					return null;
				}
			case 3:
				if(GameRule.isThree(cards)){
					return {'cardKind': GameRule.THREE,'val':cards[0].val,'size':l};
				}else{
					return null;
				}
			case 4:
				if(GameRule.isThreeWithOne(cards)){
					return {'cardKind': GameRule.THREE_WITH_ONE,'val':GameRule.getMaxVal(cards,3),'size':l};
				}else if(GameRule.isBomb(cards)){
					return {'cardKind': GameRule.BOMB,'val':cards[0].val,'size':l};
				}
				return null;
			default:
				if(GameRule.isProgression(cards)){
					return {'cardKind': GameRule.PROGRESSION,'val':cards[0].val,'size':l};
				}else if(GameRule.isProgressionPairs(cards)){
					return {'cardKind': GameRule.PROGRESSION_PAIRS,'val':cards[0].val,'size':l};
				}else if(GameRule.isThreeWithPairs(cards)){
					return {'cardKind': GameRule.THREE_WITH_PAIRS,'val':GameRule.getMaxVal(cards,3),'size':l};
				}else if(GameRule.isPlane(cards)){
					return {'cardKind': GameRule.PLANE,'val':GameRule.getMaxVal(cards,3),'size':l};
				}else if(GameRule.isPlaneWithOne(cards)){
					return {'cardKind': GameRule.PLANE_WITH_ONE,'val':GameRule.getMaxVal(cards,3),'size':l};
				}else if(GameRule.isPlaneWithPairs(cards)){
					return {'cardKind': GameRule.PLANE_WITH_PAIRS,'val':GameRule.getMaxVal(cards,3),'size':l};
				}else if(GameRule.isFourWithTwo(cards)){
					return {'cardKind': GameRule.FOUR_WITH_TWO,'val':GameRule.getMaxVal(cards,4),'size':l};
				}else if(GameRule.isFourWithPairs(cards)){
					return {'cardKind': GameRule.FOUR_WITH_TWO_PAIRS,'val':GameRule.getMaxVal(cards,4),'size':l};
				}else{
					return null;
				}
				
		}	
	}


	/**
	 * 是否是对子	
	*/
	public static isPairs(cards) {
		return cards.length == 2 && cards[0].val === cards[1].val;
	}
	/**
	 * 是否是三根
	*/
	public static isThree(cards) {
		return cards.length === 3 && cards[0].val === cards[1].val && cards[1].val === cards[2].val;
	}
	/**
	 * 是否是三带一
	*/
	public static isThreeWithOne(cards) {
		if (cards.length != 4) {
			return false;
		}
		var c = GameRule.valCount(cards);
		return c.length === 2 && (c[0].count === 3 || c[1].count === 3);
	}
	/**
	 * 是否是三带二
	*/
	public static isThreeWithPairs(cards) {
		if (cards.length != 5) {
			return false;
		}
		var c = GameRule.valCount(cards);
		return c.length == 2 && (c[0].count === 3 || c[1].count === 3);
	}
	/**
	 * 是否是顺子
	*/
	public static isProgression(cards) {
		if (cards.length < 5 || cards[0].val === 15) {
			return false;
		}
		for (var i: number = 0; i < cards.length; i++) {
			if (i != (cards.length - 1) && (cards[i].val - 1) != cards[i + 1].val) {
				return false;
			}
		}
		return true;
	}
	/**
	 * 是否是连对
	*/
	public static isProgressionPairs(cards) {
		if (cards.length < 6 || cards.length % 2 != 0 || cards[0].val === 15) {
			return false;
		}
		for (var i: number = 0; i < cards.length; i += 2) {
			if (i != (cards.length - 2) && (cards[i].val != cards[i + 1].val || (cards[i].val - 1) != cards[i + 2].val)) {
				return false;
			}
		}
		return true;
	}
	/**
	 * 是否是飞机
	*/
	public static isPlane(cards) {
		if (cards.length < 6 || cards.length % 3 != 0 || cards[0].val === 15) {
			return false;
		}
		for (var i: number = 0; i < cards.length; i += 3) {
			if (i != (cards.length - 3) && (cards[i].val != cards[i + 1].val || cards[i].val != cards[i + 2].val || (cards[i].val - 1) != cards[i + 3].val)) {
				return false;
			}
		}
		return true;
	}
	/**
	 * 是否是飞机带单
	*/
	public static isPlaneWithOne(cards) {
		if (cards.length < 8 || cards.length % 4 != 0) {
			return false;
		}
		// 牌型个数
		var c = GameRule.valCount(cards);
		// 
		var threeList = [];
		var threeCount = cards.length / 4;
		for (var i: number = 0; i < c.length; i++) {
			// 判断是否是三根
			if (c[i].count == 3) {
				threeList.push(c[i]);
			}
		}
		if (threeList.length != threeCount || threeList[0].val === 15) {
			return false;
		}
		for (var i: number = 0; i < threeList.length; i++) {
			// 判断三根是否连续
			if (i != threeList.length - 1 && threeList[i].val - 1 != threeList[i + 1].val) {
				return false;
			}
		}
		return true;
	}
	/**
	 * 是否是飞机带对
	*/
	public static isPlaneWithPairs(cards) {
		if (cards.length < 10 || cards.length % 5 != 0) {
			return false;
		}
		var c = GameRule.valCount(cards);
		var threeList = [];
		var pairsList = [];
		var groupCount = cards.length / 5;
		for (var i: number = 0; i < c.length; i++) {
			if (c[i].count == 3) {
				threeList.push(c[i]);
			} else if (c[i].count == 2) {
				pairsList.push(c[i]);
			} else {
				return false;
			}
		}
		if (threeList.length != groupCount || pairsList.length != groupCount || threeList[0].val === 15) {
			// 三根不能为2
			return false;
		}
		for (var i: number = 0; i < threeList.length; i++) {
			// 三根是否连续
			if (i != threeList.length - 1 && threeList[i].val - 1 != threeList[i + 1].val) {
				return false;
			}
		}
		return true;
	}
	/**
	 * 是否是四带二
	*/
	public static isFourWithTwo(cards) {
		var c = GameRule.valCount(cards);
		if (cards.length != 6 || c.length > 3) {
			return false;
		}
		for (var i: number = 0; i < c.length; i++) {
			if (c[i].count === 4) {
				return true;
			}
		}
		return false;
	}
	/**
	 * 是否四带两对
	*/
	public static isFourWithPairs(cards) {
		if (cards.length != 8) {
			return false;
		}
		var c = GameRule.valCount(cards);
		for (var i: number = 0; i < c.length; i++) {
			if (c[i].count != 4 && c[i].count != 2) {
				return false;
			}
		}
		return true;
	}
	/**
	 * 是否是炸弹
	*/
	public static isBomb(cards) {
		return cards.length === 4 && cards[0].val === cards[1].val && cards[0].val === cards[2].val && cards[0].val === cards[3].val;
	}
	/**
	 * 是否是王炸
	*/
	public static isKingBomb(cards) {
		return cards.length == 2 && cards[0].type == '0' && cards[1].type == '0';
	}




	/**
	 * 统计各个牌有多少张,比如2张A,一张5;
	*/
	public static valCount(cards) {
		var result = [];
		var addCount = function (result, v) {
			for (var i: number = 0; i < result.length; i++) {
				if (result[i].val == v) {
					result[i].count++;
					return;
				}
			}
			result.push({ 'val': v, 'count': 1 });
		}
		for (var i: number = 0; i < cards.length; i++) {
			addCount(result, cards[i].val);
		}
		return result;
	}
	/**
	 * 获取指定张数的最大牌值
	*/
	public static getMaxVal(cards,n) {
		var c = GameRule.valCount(cards);
		var max = 0;
		for (var i: number = 0; i < c.length; i++) {
			if(c[i].count === n && c[i].val > max){
				max = c[i].val;
			}
		}
		return max;
	}

	/*牌型*/
	public static ONE = 1;
	public static PAIRS = 2;
	public static THREE = 3;
	public static THREE_WITH_ONE = 4;
	public static THREE_WITH_PAIRS = 5;
	public static PROGRESSION = 6;
	public static PROGRESSION_PAIRS = 7;
	public static PLANE = 8;
	public static PLANE_WITH_ONE = 9;
	public static PLANE_WITH_PAIRS = 10;
	public static FOUR_WITH_TWO = 11;
	public static FOUR_WITH_TWO_PAIRS = 12;
	public static BOMB = 13;
	public static KING_BOMB = 14;
	/*错误提示*/
	public static MSG_NO_SELECT = "请选择要出的牌";
	public static MSG_ERROR_TYPE = "您选择的牌不符合游戏规则";
	public static MSG_NO_ROROB_RESTART = "所有玩家均未叫分,重新发牌";

}